接下來我們會研究一下TensorFlow的程式,怎麼訓練一個簡單的CNN卷積神經網路,去辨識圖片中的數字。
回到Anaconda,點「Home」,選Jupyter Notebook的安裝「Install」,然後開啟「Launch」。
此步驟也可以在剛剛的cmd/Terminal中進行,需要在
Windows請輸入:activate tensorflow
Mac請輸入:source activate tensorflow
進入環境中,再輸入
jupyter notebook
此時會跳到這個畫面,請記住這個目錄,之後我們會下載一些程式,放在這目錄下方便查找
例如請把檔案都下載後放在這個目錄下
請選TensorFlow的classification_cnn_mnist.ipynb
載入各種套件:
如果有還沒安裝的套件,到cmd/Terminal:
通常是「pip insall 套件名稱」、「conda install 套件名稱」就可以;如果比較複雜的,可能就需要上網查一下
import os
import pandas as pd
from pandas import DataFrame
from keras.models import Sequential, Model, load_model, Model
from keras.layers import Input, Dense, Activation, Reshape
from keras.layers import Convolution2D, MaxPooling2D, Flatten, Dropout, BatchNormalization
from keras.optimizers import Adam
from keras.utils import np_utils
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
np.random.seed(1)
from sklearn.metrics import confusion_matrix
from PIL import Image
import random
import math
下載資料:
我們會使用MNIST資料,裡面就是各種人寫的各種數字,圖片是28*28像素的灰階格式
from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.loaddata()
x_train是訓練集,y_train是辨識數字的正確答案
可以想像成
x_train = [圖片a, 圖片b, 圖片c ...]
y_train = [數字1, 數字5, 數字9 ...]
我們會用xtrain, ytrain來訓練神經網路模型,像是考前唸書
另外還有xtest, ytest,通常是數量比較少,拿來做驗證的,作為考試,來看看之前訓練的模型,學習效果如何,能不能答對之前沒看過的題目
數據前處理:
x_train = x_train.reshape(-1, 1, 28, 28)/255.
x_test = x_test.reshape(-1, 1, 28, 28)/255.
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)
改變一下數據形狀:
x_train使用把Numpy形態的Array改變一下數據形狀
reshape(-1, 1, 28, 28)的意思是:
28, 28:寬28、長28的像素,0~255的值,0代表黑色、255代表白色(所以我們的圖是黑底白字的數字)
1:灰階圖的channel只有1,如果是彩色的圖通常是3,代表rgb
-1:我們知道了1,28,28代表一張圖的資訊,但我們不知道有多少圖(圖片a, 圖片b, 圖片c ...),-1的意思是有剩下的數字有多少都放這兒,意思就是還有多少圖就放這。那為甚麼不設定個定值呢?因為圖的數量有可能增加或減少,先不寫死,讓程式自己去算就好
/255:除255之後,本來0~255的值就會變成0~1,但數值的分佈比例還是一樣的,在機器學習中,我們常用正規化,把值變成0~1或是-1~1,方便訓練
獨熱編碼One-hot:
np_utils.to_categorical(y_train, num_classes=10):
我們的標籤y_train本來的答案是標籤編碼: [1, 5, 9 ...],也是因為機器學習中,我們常用獨熱編碼,把標籤編碼轉成獨熱編碼
因此數字的0~9,會有以下的轉變:
0 -> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
1 -> [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
2 -> [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
3 -> [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
4 -> [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
5 -> [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
6 -> [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
7 -> [0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
8 -> [0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
9 -> [0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
所以 y_train 標籤編碼 -> 獨熱編碼:
[1, 5, 9 ...]
->
[[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
...]
為什麼要做這樣的編碼呢?
白話來說是因為1,3,5對機器其實有越來越大的意義,但數字在此僅代表是圖片寫了什麼數字,不代表數字大有更大的意義
轉成獨熱編碼[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],1代表有、0代表沒有,1出現在第一個位置,我們規定那代表0這個數字
將來我們神經模型如果預測出這樣的結果:[0.3, 0.6, 0.05, 0, 0.05, 0, 0, 0, 0, 0]
全部加裡來總和為1(0.3 + 0.6 + 0.05 + 0.05 = 1)
模型認為是數字0的可能性為0.3
模型認為是數字1的可能性為0.6
模型認為是數字2的可能性為0.05
模型認為是數字4的可能性為0.05
最後判定數字1的可能性最大,因此預測答案是數字1